package de.revdev.streckenliste.managedbeans;

import de.revdev.streckenliste.dao.SlAEintragDAO;
import de.revdev.streckenliste.dao.SlBEintragDAO;
import de.revdev.streckenliste.dao.StreckenlisteDAO;
import de.revdev.streckenliste.dao.WildtypDAO;
import de.revdev.streckenliste.entities.AbschPlEintrag;
import de.revdev.streckenliste.entities.Abschussplan;
import de.revdev.streckenliste.entities.SlAEintrag;
import de.revdev.streckenliste.entities.SlBEintrag;
import de.revdev.streckenliste.entities.SlBEintrag.AuffundArt;
import de.revdev.streckenliste.entities.Streckenliste;
import de.revdev.streckenliste.entities.Wildart;
import de.revdev.streckenliste.entities.Wildtyp;
import java.io.Serializable;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.LinkedList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.inject.Inject;
import javax.inject.Named;
import org.primefaces.event.SelectEvent;
import org.primefaces.event.TabChangeEvent;
import org.primefaces.event.UnselectEvent;

/**
 *
 * @author f.lindermaier
 */
@Named(value = "streckenlisteBean")
@SessionScoped
public class StreckenlisteBean implements Serializable {

    public enum SlEintragArt {

        A, B, AB
    };
    @Inject
    private NavigationBean nbean;
    @Inject
    private WildtypDAO wtdao;
    @Inject
    private SlAEintragDAO slaedao;
    @Inject
    private SlBEintragDAO slbedao;
    @Inject
    private StreckenlisteDAO sldao;
    private Wildtyp wt;
    private Wildart wa;
    private int anzahlErlegt;
    private int anzahlVerendet;
    private int anzahlUnfall;
    private Date tag;
    private double gewicht;
    private AuffundArt auffundart;
    private List<Wildart> lstWA;
    private SlEintragArt slEintragArt;
    private String bemerkung;
    private UIComponent msg;
    private UIComponent cal;
    private SlBEintrag slbe;
    private SlAEintrag slae;
    private Abschussplan selectedAbschussplan;
    private int tabIndex;

    /**
     * Creates a new instance of StreckenlisteBean
     */
    public StreckenlisteBean() {
    }

    @PostConstruct
    private void init() {
        tabIndex = 0;
        slEintragArt = SlEintragArt.B;
        slae = new SlAEintrag();
        slbe = new SlBEintrag();
    }

    public List<Wildtyp> holeWildtyp() {
        List<Wildtyp> lst = wtdao.findWtSortiert();
        return lst;
    }

    public List<Wildart> holeWildart() {
        if (wt == null) {
            return null;
        }
        return wt.getWildart();
    }

    private void clear() {
        wt = null;
        wa = null;
        anzahlErlegt = 0;
        anzahlVerendet = 0;
        anzahlVerendet = 0;
        tag = null;
        gewicht = 0;
        auffundart = null;
        lstWA = null;
        slEintragArt = SlEintragArt.A;
        bemerkung = null;
        slae = new SlAEintrag();
        slbe = new SlBEintrag();
        tabIndex = 0;
    }

    public List<SlAEintrag> holeListeA() {
        Streckenliste temp = nbean.getSelectedStreckenliste();
        return temp.getSlAEntries();
    }

    public List<SlBEintrag> holeListeAB() {
        List<SlBEintrag> lst = new LinkedList<>();
        for (Wildart wildart : wtdao.findByName("Schwarzwild").getWildart()) {
            SlBEintrag slBEintrag = new SlBEintrag();
            slBEintrag.setWildtyp(wildart.getWildtyp());
            slBEintrag.setWildart(wildart);
            slBEintrag.setStreckenliste(nbean.getSelectedStreckenliste());
            slBEintrag.setErlegt(Integer.parseInt(Long.toString(slaedao.count(wildart, AuffundArt.ERLEGT, slBEintrag.getStreckenliste()))));
            slBEintrag.setVerendet(Integer.parseInt(Long.toString(slaedao.count(wildart, AuffundArt.VERENDET, slBEintrag.getStreckenliste()))));
            slBEintrag.setUnfall(Integer.parseInt(Long.toString(slaedao.count(wildart, AuffundArt.UNFALL, slBEintrag.getStreckenliste()))));
            lst.add(slBEintrag);
        }
        List<SlBEintrag> tmpLst = new LinkedList<>(lst);
        for (SlBEintrag slb : tmpLst) {
            if (slb.getErlegt() == 0 && slb.getVerendet() == 0 && slb.getUnfall() == 0) {
                lst.remove(slb);
            }
        }
        SlBEintrag tmp = null;
        Wildart nWa = new Wildart();
        nWa.setId(new Long(100000000));
        nWa.setNameWA("Frischlinge");
        tmpLst = new LinkedList<>(lst);
        for (SlBEintrag slb : tmpLst) {
            if (slb.getWildart().getNameWA().equals("Frischlinge m") || slb.getWildart().getNameWA().equals("Frischlinge w")) {
                if (tmp == null) {
                    tmp = new SlBEintrag();
                }
                tmp.setWildart(wa);
                tmp.setErlegt(tmp.getErlegt() + slb.getErlegt());
                tmp.setUnfall(tmp.getUnfall() + slb.getUnfall());
                tmp.setVerendet(tmp.getVerendet() + slb.getVerendet());
                lst.remove(slb);
            }
        }
        if (tmp != null) {
            tmp.setWildart(nWa);
            lst.add(tmp);
        }
        return lst;
    }

    public List<SlBEintrag> holeListeB() {
        List<SlBEintrag> lst = new LinkedList<>();
        for (SlBEintrag e : nbean.getSelectedStreckenliste().getSlBEntries()) {
            if (!e.getWildtyp().isAbschPlPfl()) {
                lst.add(e);
            }
        }
        return lst;
    }

    public void prüfeWA() {
        if (wt != null && wt.getWildart() != null && !wt.getWildart().isEmpty()) {
            slEintragArt = SlEintragArt.A;
        } else {
            slEintragArt = SlEintragArt.B;
            for (SlBEintrag e : nbean.getSelectedStreckenliste().getSlBEntries()) {
                if (e.getWildtyp().equals(wt)) {
                    FacesContext.getCurrentInstance().addMessage(msg.getClientId(), new FacesMessage(FacesMessage.SEVERITY_INFO, "Der vorhandene Eintrag für " + wt.getNameWT() + " wurde geladen!", "Der vorhandene Eintrag für " + wt.getNameWT() + " wurde geladen!"));
                    slbe = e;
                    anzahlErlegt = e.getErlegt();
                    anzahlVerendet = e.getVerendet();
                    anzahlUnfall = e.getUnfall();
                    bemerkung = e.getBemerkung();
                }
            }
        }
    }

    public void speichern(ActionEvent event) {
        try {

            if (slEintragArt == SlEintragArt.A) {
                String year = nbean.getSelectedStreckenliste().getJagdJahr();
                Calendar startJagdJahr = new GregorianCalendar(Integer.parseInt(year), Calendar.MARCH, 31);
                Calendar endJagdJahr = new GregorianCalendar(Integer.parseInt(year) + 1, Calendar.APRIL, 1);
                System.out.println(tag.toString());
                System.out.println(startJagdJahr.get(Calendar.DAY_OF_MONTH) + ":" + startJagdJahr.get(Calendar.MONTH) + ":" + startJagdJahr.get(Calendar.YEAR));
                System.out.println(endJagdJahr.get(Calendar.DAY_OF_MONTH) + ":" + endJagdJahr.get(Calendar.MONTH) + ":" + endJagdJahr.get(Calendar.YEAR));
                if (!(tag.after(startJagdJahr.getTime()) && tag.before(endJagdJahr.getTime()))) {
                    throw new Exception();
                }
                slae.setAbschTag(tag);
                slae.setBemerkung(bemerkung);
                slae.setWildart(wa);
                slae.setGewicht(gewicht);
                slae.setAuffundart(auffundart);
                slae.setStreckenliste(nbean.getSelectedStreckenliste());
                slaedao.create(slae);
                nbean.getSelectedStreckenliste().getSlAEntries().add(slae);
            } else if (slEintragArt == SlEintragArt.B) {
                slbe.setBemerkung(bemerkung);
                slbe.setErlegt(anzahlErlegt);
                slbe.setVerendet(anzahlVerendet);
                slbe.setUnfall(anzahlUnfall);
                slbe.setWildtyp(wt);
                slbe.setStreckenliste(nbean.getSelectedStreckenliste());
                if (slbe.getId() != null) {
                    slbedao.edit(slbe);
                } else {
                    slbedao.create(slbe);
                    nbean.getSelectedStreckenliste().getSlBEntries().add(slbe);
                }
            }
            nbean.setSelectedStreckenliste(sldao.refresh(nbean.getSelectedStreckenliste()));
            nbean.refreshModel();
            clear();
        } catch (Exception e) {
            FacesContext fc = FacesContext.getCurrentInstance();
            fc.addMessage(cal.getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Der Tag liegt ausserhalb des Berichtszeitraums.", "Der Tag liegt ausserhalb des Berichtszeitraums."));
        }
    }

    public String streckenlisteAbschliessen() {
        nbean.getSelectedStreckenliste().setIstAbgeschlossen(true);
        sldao.edit(nbean.getSelectedStreckenliste());
        return "/faces/user/streckenliste.xhtml?faces-redirect=true";
    }

    public List<Abschussplan> holeAbschussplanEintrag() {
        List<Abschussplan> lst = new LinkedList<>();
        String tmp = nbean.getSelectedStreckenliste().getJagdJahr();
        int jahrSl = new Integer(tmp);
        for (Abschussplan a : nbean.getSelectedRevier().getAbschussplaene()) {
            int jahrAbschPlStart = new Integer(a.getJahr());
            int jahrAbschPlEnde = jahrAbschPlStart + a.getWildtyp().getDauerAbschPL() - 1;
            if (jahrSl >= jahrAbschPlStart && jahrSl <= jahrAbschPlEnde) {
                lst.add(a);
            }
        }
        return lst;
    }

    public int cntIstAbschPl(Abschussplan abschussplan) {
        int tmp = 0;
        for (SlAEintrag e : nbean.getSelectedStreckenliste().getSlAEntries()) {
            if (e.getWildart().getWildtyp().equals(abschussplan.getWildtyp())) {
                tmp += 1;
            }
        }
        return tmp;
    }

    public int sollIstAbschpl(Abschussplan abschussplan) {
        int tmp = 0;
        for (SlAEintrag e : nbean.getSelectedStreckenliste().getSlAEntries()) {
            if (e.getWildart().getWildtyp().equals(abschussplan.getWildtyp())) {
                tmp += 1;
            }
        }

        return (int) ((tmp * 1.0 / abschussplan.calcGesamtZahl() * 1.0) * 100);
    }

    public int cntIstAbschplEintrag(AbschPlEintrag abschPlEintrag) {
        int tmp = 0;
        for (SlAEintrag e : nbean.getSelectedStreckenliste().getSlAEntries()) {
            if (e.getWildart().equals(abschPlEintrag.getWildart())) {
                tmp += 1;
            }
        }
        return tmp;
    }

    public int sollIstAbschplEintrag(AbschPlEintrag abschPlEintrag) {
        int tmp = 0;
        for (SlAEintrag e : nbean.getSelectedStreckenliste().getSlAEntries()) {
            if (e.getWildart().equals(abschPlEintrag.getWildart())) {
                tmp += 1;
            }
        }

        return (int) ((tmp * 1.0 / abschPlEintrag.getAnzahl() * 1.0) * 100);
    }

    public List<AbschPlEintrag> holeAbschPlEintragListe() {
        if (selectedAbschussplan != null) {
            return selectedAbschussplan.getEintrag();
        }
        return null;
    }

    public boolean slAEintragRendered() {
        if (slEintragArt == SlEintragArt.A || slEintragArt == SlEintragArt.AB) {
            return true;
        }
        return false;
    }

    public boolean slBEintragRendered() {
        if (slEintragArt == SlEintragArt.B || slEintragArt == SlEintragArt.AB) {
            return true;
        }
        return false;
    }

    public List<SlAEintrag> holeZusammnefassung() {
        List<SlAEintrag> lst = new LinkedList<>();
        for (SlAEintrag e : nbean.getSelectedStreckenliste().getSlAEntries()) {
            if (e.getWildart().getNameWA().equals("Frischlinge m") || e.getWildart().getNameWA().equals("Frischlinge w")) {
                SlAEintrag n = new SlAEintrag();
                Wildart nWa = new Wildart();
                nWa.setNameWA("Frischlinge");
                nWa.setWildtyp(e.getWildart().getWildtyp());
                nWa.setId(new Long(1000000000));
                n.setWildart(nWa);
                if (!checkVorhanden(lst, n)) {
                    lst.add(n);
                }
            } else {
                if (!checkVorhanden(lst, e)) {
                    lst.add(e);
                }
            }

        }
        return lst;
    }

    private boolean checkVorhanden(List<SlAEintrag> lst, SlAEintrag eintrag) {
        for (SlAEintrag e : lst) {
            if (e.getWildart().equals(eintrag.getWildart())) {
                return true;
            }
        }
        return false;
    }

    public int cntSLAGeschossen(SlAEintrag sla) {
        int tmp = 0;
        if (sla.getWildart().getId() == 1000000000) {
            for (SlAEintrag e : nbean.getSelectedStreckenliste().getSlAEntries()) {
                if ((e.getWildart().getNameWA().equals("Frischlinge w") || e.getWildart().getNameWA().equals("Frischlinge m"))
                        && e.getAuffundart().equals(AuffundArt.ERLEGT)) {
                    tmp++;
                }
            }
        } else {
            for (SlAEintrag e : nbean.getSelectedStreckenliste().getSlAEntries()) {
                if (e.getWildart().equals(sla.getWildart()) && e.getAuffundart().equals(AuffundArt.ERLEGT)) {
                    tmp++;
                }
            }
        }
        return tmp;
    }

    public int cntSLAVerendet(SlAEintrag sla) {
        int tmp = 0;
        if (sla.getWildart().getId() == 1000000000) {
            for (SlAEintrag e : nbean.getSelectedStreckenliste().getSlAEntries()) {
                if ((e.getWildart().getNameWA().equals("Frischlinge w") || e.getWildart().getNameWA().equals("Frischlinge m"))
                        && (e.getAuffundart().equals(AuffundArt.VERENDET) || e.getAuffundart().equals(AuffundArt.UNFALL))) {
                    tmp++;
                }
            }
        } else {
            for (SlAEintrag e : nbean.getSelectedStreckenliste().getSlAEntries()) {
                if (e.getWildart().equals(sla.getWildart())
                        && (e.getAuffundart().equals(AuffundArt.VERENDET) || e.getAuffundart().equals(AuffundArt.UNFALL))) {
                    tmp++;
                }
            }
        }
        return tmp;
    }

    public List<String> holeWildtypNamen() {
        List<Wildtyp> lstwt = wtdao.findAll();
        List<String> lstwtn = new LinkedList<>();
        for (Wildtyp wildtyp : lstwt) {
            if (wildtyp.isAbschPlPfl()) {
                lstwtn.add(wildtyp.getNameWT());
            }
        }
        return lstwtn;
    }

    public void onTabChange(TabChangeEvent event) {
        if ("tabv_sl:tab_overview".equals(event.getTab().getClientId())) {
            tabIndex = 0;
        }
        if ("tabv_sl:tab_sla".equals(event.getTab().getClientId())) {
            tabIndex = 1;
        }
        if ("tabv_sl:tab_slb".equals(event.getTab().getClientId())) {
            tabIndex = 2;
        }
        if ("tabv_sl:tab_edit".equals(event.getTab().getClientId())) {
            tabIndex = 3;
        }
        if ("tabv_sl:tab_close".equals(event.getTab().getClientId())) {
            tabIndex = 4;
        }
    }

    public void onRowSelect(SelectEvent event) {
    }

    public void onRowUnselect(UnselectEvent event) {
        selectedAbschussplan = null;
    }

    public String cancel() {
        tabIndex = 0;
        return "/faces/user/streckenliste.xhtml?faces-redirect=true";
    }

    public void loescheSLA(ActionEvent event) {
        SlAEintrag tmp = (SlAEintrag) event.getComponent().getAttributes().get("sla");
        slaedao.remove(tmp);
        nbean.getSelectedStreckenliste().getSlAEntries().remove(tmp);
    }

    public NavigationBean getNbean() {
        return nbean;
    }

    public void setNbean(NavigationBean nbean) {
        this.nbean = nbean;
    }

    public Wildtyp getWt() {
        return wt;
    }

    public void setWt(Wildtyp wt) {
        anzahlErlegt = 0;
        anzahlUnfall = 0;
        anzahlVerendet = 0;
        bemerkung = "";
        tag = null;
        auffundart = null;
        gewicht = 0;
        this.wt = wt;
    }

    public Wildart getWa() {
        return wa;
    }

    public void setWa(Wildart wa) {
        this.wa = wa;
    }

    public Date getTag() {
        return tag;
    }

    public void setTag(Date tag) {
        this.tag = tag;
    }

    public double getGewicht() {
        return gewicht;
    }

    public void setGewicht(double gewicht) {
        this.gewicht = gewicht;
    }

    public AuffundArt getAuffundart() {
        return auffundart;
    }

    public void setAuffundart(AuffundArt auffundart) {
        this.auffundart = auffundart;
    }

    public SlEintragArt getSlEintragArt() {
        return slEintragArt;
    }

    public void setSlEintragArt(SlEintragArt slEintragArt) {
        this.slEintragArt = slEintragArt;
    }

    public List<Wildart> getLstWA() {
        return lstWA;
    }

    public void setLstWA(List<Wildart> lstWA) {
        this.lstWA = lstWA;
    }

    public String getBemerkung() {
        return bemerkung;
    }

    public void setBemerkung(String bemerkung) {
        this.bemerkung = bemerkung;
    }

    public int getAnzahlErlegt() {
        return anzahlErlegt;
    }

    public void setAnzahlErlegt(int anzahlErlegt) {
        this.anzahlErlegt = anzahlErlegt;
    }

    public int getAnzahlVerendet() {
        return anzahlVerendet;
    }

    public void setAnzahlVerendet(int anzahlVerendet) {
        this.anzahlVerendet = anzahlVerendet;
    }

    public int getAnzahlUnfall() {
        return anzahlUnfall;
    }

    public void setAnzahlUnfall(int anzahlUnfall) {
        this.anzahlUnfall = anzahlUnfall;
    }

    public UIComponent getMsg() {
        return msg;
    }

    public void setMsg(UIComponent msg) {
        this.msg = msg;
    }

    public SlBEintrag getSlbe() {
        return slbe;
    }

    public void setSlbe(SlBEintrag slbe) {
        this.slbe = slbe;
    }

    public SlAEintrag getSlae() {
        return slae;
    }

    public void setSlae(SlAEintrag slae) {
        this.slae = slae;
    }

    public Abschussplan getSelectedAbschussplan() {
        return selectedAbschussplan;
    }

    public void setSelectedAbschussplan(Abschussplan selectedAbschussplan) {
        this.selectedAbschussplan = selectedAbschussplan;
    }

    public int getTabIndex() {
        return tabIndex;
    }

    public void setTabIndex(int tabIndex) {
        this.tabIndex = tabIndex;
    }

    public UIComponent getCal() {
        return cal;
    }

    public void setCal(UIComponent cal) {
        this.cal = cal;
    }
}
